/*
 * This file is part of Catfish.
 * Copyright (C) 2010 Namazu Studios LLC
 * 
 * Catfish is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as 
 * published by the Free Software Foundation, either version 3 of 
 * the License, or (at your option) any later version.
 * 
 * Catfish is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with Catfish.  If not, please visit:
 *  
 * http://www.gnu.org/licenses/
 *  
 */
package com.namazustudios.catfish.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * Indicates that the given field or property method is to be persisted in the
 * datastore. Using the default rules, It must be a type supported by the
 * datastore. If an Entity in the datastore does not contain a property, it will
 * use a ValueProvider to set the value. This is useful if code is refactored
 * and fields are added to existing properties.
 * 
 * A special rule may be implemented as a Converter. This allows the user to
 * specify a class used to convert values to and from suitable datastore types.
 * Catfish provides a set of default converters.
 * 
 * If this annotation appears on a Collection, it will attempt to store the
 * whole collection. Each element of the collection will pass through the
 * appropriate Converter before going to and from the datastore. If the
 * Collection contains null values, it will pass those through to the datastore.
 * When Unmarshalling, those null may be fetched. In which case, the Collection
 * type must support null values or the unmarshalling process will fail.
 * 
 * @author patricktwohig
 * 
 */
@Retention(RetentionPolicy.RUNTIME)
@Target( { ElementType.FIELD, ElementType.ANNOTATION_TYPE })
public @interface Property {

    /**
     * Gets the name of the property on the Entity. If left unspecified, this
     * will use the name of the annotated field.
     * 
     * @return the name of the Property.
     */
    public String name() default "";

    /**
     * Specifies the name of a ValueProvider object. If left unspecified, this
     * will use the default provider specified as "default". A ValueProvider may
     * provide any type, not just values restricted to Datastore safe values.
     * 
     * If the annotated field is a Collection, then this must provide a value
     * for the whole collection not individual elements.
     * 
     * @return the name of the provider to use
     */
    public String provider() default "default";

    /**
     * Specifies the name of the validator use to validate this property. If
     * specified, the value of the field will be passed through the validator
     * during serialization. If no validator is specified, validation is skipped
     * for this field.
     * 
     * If the annotated field is a Collection, each value of the Collection is
     * validated rather than the collection as a whole.
     * 
     * @return the validator's name
     */
    public String validator() default "";

    /**
     * Specifies the converter associated with the given type. If left blank,
     * the value will not be converted.
     * 
     * If the annotated field is a Collection, each value of the Collection is
     * converted rather than the collection as a whole.
     * 
     * @return the converter
     */
    public String converter() default "";

}
